﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ERPStore.Web.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Web.Logging
{
	public class WebApiTraceWriter : System.Web.Http.Tracing.ITraceWriter
	{
		public WebApiTraceWriter(ERPStore.Logging.ILogger logger)
		{
			this.Logger = logger;
		}

		protected ERPStore.Logging.ILogger Logger { get; private set; }

		#region ITraceWriter Members

		public bool IsEnabled(string category, System.Web.Http.Tracing.TraceLevel level)
		{
			return true;
		}

		public void Trace(System.Net.Http.HttpRequestMessage request, string category, System.Web.Http.Tracing.TraceLevel level, Action<System.Web.Http.Tracing.TraceRecord> traceAction)
		{
			if (level == System.Web.Http.Tracing.TraceLevel.Off)
			{
				return;
			}

			var record = new System.Web.Http.Tracing.TraceRecord(request, category, level);
			traceAction(record);

			var ex = record.Exception;
			switch (level)
			{
				case System.Web.Http.Tracing.TraceLevel.Debug:
					if (GlobalConfiguration.Configuration.DebugEnabled)
					{
						Logger.Debug(CreateDebugInfo(record, request));
					}
					break;
				case System.Web.Http.Tracing.TraceLevel.Error:
					if (!ex.Data.Contains("RequestDebugInfos"))
					{
						ex.Data.Add("RequestDebugInfos", CreateDebugInfo(record, request));
					}
					Logger.Error(ex);
					break;
				case System.Web.Http.Tracing.TraceLevel.Fatal:
					if (!ex.Data.Contains("RequestDebugInfos"))
					{
						ex.Data.Add("RequestDebugInfos", CreateDebugInfo(record, request));
					}
					Logger.Fatal(ex);
					break;
				case System.Web.Http.Tracing.TraceLevel.Info:
					if (GlobalConfiguration.Configuration.DebugEnabled)
					{
						Logger.Info(CreateDebugInfo(record, request));
					}
					break;
				case System.Web.Http.Tracing.TraceLevel.Off:
					break;
				case System.Web.Http.Tracing.TraceLevel.Warn:
					Logger.Warn(CreateDebugInfo(record, request));
					break;
				default:
					break;
			}
		}

		public string CreateDebugInfo(System.Web.Http.Tracing.TraceRecord record, System.Net.Http.HttpRequestMessage request)
		{
			var result = string.Empty;
			var debugInfo = new List<string>();
			try
			{
				debugInfo.Add(string.Format("Category : {0}", record.Category));
				if (record.Request != null)
				{
					debugInfo.Add(string.Format("Method : {0}", record.Request.Method));
					debugInfo.Add(string.Format("Url : {0}", record.Request.RequestUri));
					debugInfo.Add(string.Format("Content : {0}", record.Request.Content));
				}
				debugInfo.Add(string.Format("Message : {0}", record.Message));
				debugInfo.Add(string.Format("Operation : {0}", record.Operation));
				debugInfo.Add(string.Format("Operator : {0}", record.Operator));
				debugInfo.Add(string.Format("Status : {0}", record.Status));
				var requestBase = request.GetRequestBase();
				if (requestBase != null)
				{
					debugInfo.Add(string.Format("UserAgent : {0}", requestBase.UserAgent));
				}
				debugInfo.Add(string.Format("IP : {0}", request.GetClientIpAddress()));

				result = debugInfo.JoinString(System.Environment.NewLine);
			}
			catch (Exception apiex)
			{
				Logger.Error(apiex);
			}
			return result;
		}

		#endregion
	}
}
